/*!
 * \file Reserva.h
 *
 * \date Jul 8, 2014
 * \author correa
 */
#ifndef RESERVA_H_
#define RESERVA_H_

#include <set>
#include <Solucion.h>
#include <ProjectableVertexSet.h>
#include <list>

using namespace std;

class ReservaNode;
class ReservaClique;

struct ReservaNodeComp {
  bool operator() (ReservaNode * const& lhs, ReservaNode * const& rhs) const;
};

class ReservaNode
{
	friend struct ReservaNodeComp;
	friend class ReservaClique;
	friend class ReservaInterno;

protected:
	int		_vertice;
	int		_npruebas;

	ReservaNode() : _vertice(-1), _npruebas(0) {};
	ReservaNode(int v) : _vertice(v), _npruebas(0) {};

public:
	virtual ~ReservaNode() {};
};

class ReservaInterno : public ReservaNode
{
	friend class ReservaClique;

protected:
	set<ReservaNode *, ReservaNodeComp>	_proximoTermo;

	bool buscaCliqueVioladasRecursivo(ReservaClique * r, int nmax);
	void printRecursivo(VertexSet& v);

	ReservaInterno() : ReservaNode(), _proximoTermo() {};
	ReservaInterno(int v) : ReservaNode(v), _proximoTermo() {};

public:
	virtual ~ReservaInterno();
};

class ReservaClique : public ReservaInterno
{
	friend class ReservaInterno;

	int						_n;
	bool					_activa;
	VertexSet				_vertices;
	Solucion *				_solucion;
	double 					_violacionMinima;
	list<ProjectableCliqueSet *>*_desigualdades;
	double 					_soma;
	double 					_tamano;
	int						_nclique;
	int						_nrango;
	int						_nprango;
	int						_nvioladas;

public:
	ReservaClique(int n);
	virtual ~ReservaClique();

	bool hayClique();
	bool tieneClique(const VertexSet& clique);
	void agregaClique(const VertexSet& clique);
	int buscaCliqueVioladas(Solucion& solucion, double violacionMinima, int nmax, list<ProjectableCliqueSet *>& desigualdades);
	void haceInactiva();
	void haceActiva();
	bool esActiva();
	int cliqueVioladas();
	int rangoVioladas();
	int prangoVioladas();
	void print();
};

inline bool ReservaNodeComp::operator() (ReservaNode * const& lhs, ReservaNode * const& rhs) const {
	return lhs->_vertice < rhs->_vertice;
}

#endif /* RESERVA_H_ */
